import React, { PureComponent } from 'react'
import {
  Button, Form, InputNumber, message, Modal, Popconfirm, Select, Steps, Upload,
} from 'antd'
import FieldMapping from 'react-field-mapping'
import {
  CreateDiffEditor, InputSearch, Logger, ProTable, ProTableOperate, ProTableOptions,
} from '@/components'
import Tools from '@/utils/Tools'
import {
  createSql,
  createTable,
  deleteDocumentCapture,
  fileParsing,
  getData,
  getLog,
  getTableField,
  getTableList,
  saveTaskWithFromText,
} from './api'
import { SUAN_PAN } from '@/utils/https'
import styles from './index.less'

const { Dragger } = Upload
const { Step } = Steps
const { Option } = Select
const { OperateItem } = ProTableOperate
const { Item } = Form
const statusObj = {
  0: {
    key: 5,
    value: '成功',
    icon: 'icon-chenggong',
    color: '#43A047',
  },
  1: {
    key: 6,
    value: '失败',
    icon: 'icon-shibai1',
    color: '#EF5350',
  },
  2: {
    key: 7,
    value: '同步中',
    icon: 'icon-yunhangzhong_1',
    color: '#43A047',
  },
}
const sourceCols = [
  { title: '字段', key: 'fieldName' },
]
const targetCols = [
  { title: '字段', key: 'fieldName' },
  { title: '类型', key: 'fieldType' },
  { title: '描述', key: 'comment' },
]
export default class DataManager extends PureComponent {
  constructor(props) {
    super(props)
    this.state = {
      query: {},
      id: null,
      tableName: '',
      current: 0,
      previewData: {
        columns: [],
        data: [],
      },
      previewData2: {
        columns: [],
        data: [],
      },
      encodeFormat: 'UTF-8',
      fileName: null,
      filePath: null,
      fileDownloadPath: null,
      sourceFields: [],
      targetFields: [],
      relation: [],
      scripts: '',
      dataReplaceRuleId: 1,
      isSkip: true,
      tblId: null,
      table: null,
      btnSelectIndex: null,
      colNum: 0,
      parsingData: [],
      skipCount: 1,
    }
    this.time = null
    this.time2 = null
    this.logger = React.createRef()
  }

  componentDidMount() {
    const {
      sourceFields, targetFields, relation,
    } = this.state
    window.onresize = () => {
      clearTimeout(this.time)
      this.time = setTimeout(() => {
        this.setState({
          sourceFields,
          targetFields,
          relation: [],
        }, () => {
          this.setState({
            relation,
          })
        })
      }, 500)
    }
    this.getTableList()
    this.setTimeout()
  }

  componentWillUnmount() {
    this.time2 && clearTimeout(this.time2)
    this.time && clearTimeout(this.time)
  }

  setTimeout = () => {
    const { tableName } = this.state
    clearTimeout(this.time2)
    this.time2 = setTimeout(() => {
      this.setState({
        query: {
          tableName,
        },
      })
      this.setTimeout()
    }, 3000)
  }

  getTableList = () => {
    getTableList().then((data) => {
      this.setState({
        tableList: data,
      })
    })
  }

  deleteDocumentCapture = (id) => {
    this.setState({
      visibleDele: true,
    })
    deleteDocumentCapture({ id }).then((data) => {
      const { tableName } = this.state
      this.setState({
        visibleDele: false,
        query: {
          tableName,
        },
      })
    })
  }

  getData = (targetTblName) => {
    getData({ targetTblName }).then((res) => {
      this.setState({
        dataShows: true,
      })
      if (res.status === 200) {
        const data = []
        const columns = []
        res.data.columns
          && res.data.columns.map((name, i) => {
            columns.push({
              title: name,
              dataIndex: name,
              key: name,
              width: 100,
            })
          })
        res.data.rows
          && res.data.rows.map((arr, key) => {
            const dataObj = { key }
            res.data.columns
              && res.data.columns.map((name, i) => {
                dataObj[name] = arr[i]
              })
            data.push(dataObj)
          })
        this.setState({
          previewData2: {
            columns,
            data,
          },
        })
      } else {
        message.error(res.msg)
      }
    })
  }

  getTableField = (tblName) => {
    getTableField({ tblName }).then((data) => {
      data.map((item) => {
        item.key = item.fieldName
      })
      this.setState({
        targetFields: data,
      })
    })
  }

  fileParsing = (file) => {
    const formData = new FormData()
    const { encodeFormat } = this.state
    formData.append(
      'file',
      new window.File([file], file.name, { type: file.type }),
    )
    formData.append(
      'encodeFormat',
      encodeFormat,
    )

    fileParsing(formData).then((data) => {
      this.setData(data)
    })
  }

  setData = (data) => {
    const length = this.getMaxLength(data)
    const datas = []
    const columns = []
    const sourceFields = []
    for (let i = 0; i < length; i++) {
      columns.push({
        title: i,
        dataIndex: i,
        key: i,
        width: 100,
        ellipsis: true,
      })
      sourceFields.push({
        fieldName: `第${i + 1}列（${data ? data[0][i] : ''}）`,
        key: `${i}`,
        name: data ? data[0][i] : '',
      })
    }
    data && data.map((arr, key) => {
      const dataObj = { key }
      for (let i = 0; i < length; i++) {
        dataObj[i] = arr[i] === undefined ? '' : arr[i]
      }
      datas.push(dataObj)
    })
    this.setState({
      previewData: {
        columns,
        data: datas,
      },
      sourceFields,
      parsingData: data || [],
    })
  }

  getMaxLength = (data) => {
    let length = 0
    data && data.map((arr) => {
      if (arr && arr.length > length) {
        length = arr.length
      }
    })
    this.setState({
      colNum: length,
    })
    return length
  }

  // 同行映射
  sameLine = () => {
    const { sourceFields, targetFields } = this.state
    const len = sourceFields.length > targetFields.length
      ? targetFields.length
      : sourceFields.length
    const relation = []
    for (let i = 0; i < len; i++) {
      relation.push({
        source: {
          ...sourceFields[i],
        },
        target: {
          ...targetFields[i],
        },
      })
    }
    this.setState({
      relation,
      btnSelectIndex: 0,
    })
  }

  // 同名映射
  sameName = () => {
    const { sourceFields, targetFields } = this.state
    const relation = []
    sourceFields.map((item) => {
      targetFields.map((n) => {
        if (item.name.toLowerCase() === n.fieldName.toLowerCase()) {
          relation.push({
            source: {
              ...item,
            },
            target: {
              ...n,
            },
          })
        }
        return null
      })
      return null
    })

    this.setState({
      relation,
      btnSelectIndex: 1,
    })
  }

  /**
   * sql语句发生改变
   */
  valueChange = (scripts) => {
    this.setState({
      scripts,
    })
  };

  clear = () => {
    this.setState({
      visible: false,
      current: 0,
      previewData: {
        columns: [],
        data: [],
      },
      tblId: null,
      table: null,
      sourceFields: [],
      targetFields: [],
      relation: [],
      skipCount: 1,
    })
  }

  createTable = () => {
    const { scripts } = this.state
    createTable({ scripts }).then((res) => {
      if (res.status === 200) {
        this.getTableList()
        this.setState({
          isShows: false,
          table: res.data && res.data.tableName,
          tblId: res.data && res.data.tblIdStr,
        }, () => {
          this.getTableField(res.data && res.data.tableName)
        })
        message.success(res.msg)
      } else {
        message.error(res.msg)
      }
    })
  }

  saveTaskWithFromText = () => {
    const {
      dataReplaceRuleId, fileName, filePath, isSkip, table, tblId, relation, tableName, fileDownloadPath, encodeFormat, skipCount,
    } = this.state

    const tbTaskFieldMapEntities = []
    relation && relation.length && relation.map((item) => {
      tbTaskFieldMapEntities.push({
        isSourceFieldPk: 0,
        isTargetFieldPk: item.target.pk ? 1 : 0,
        sourceField: item.source.key,
        sourceFieldType: 'string',
        targetField: item.target.fieldName,
        targetFieldType: item.target.fieldType,
      })
    })
    if (tbTaskFieldMapEntities && tbTaskFieldMapEntities.length) {
      saveTaskWithFromText({
        dataReplaceRuleId, fileName, filePath, fileDownloadPath, tableName: table, tblId, tbTaskFieldMapEntities, encodeFormat, skipCount,
      }).then((res) => {
        if (res.status === 200) {
          this.clear()
          this.setState({
            query: {
              tableName,
            },
          })
          message.success(res.msg)
        } else {
          message.error(res.msg)
        }
      })
    } else {
      message.error('字段映射不能为空')
    }
  }

  createSql = () => {
    const { colNum, fileName, parsingData } = this.state

    createSql({
      // colNum,
      fileName,
      columnNames: parsingData?.[0] || [],
    }).then((res) => {
      if (res.status === 200) {
        this.setState({
          scripts: res.data,
          isShows: true,
        })
        message.success(res.msg || '操作成功')
      } else {
        message.error(res.msg || '服务端错误')
      }
    })
  }

  getLog = (id) => {
    this.logger.current.iconUpFn()
    getLog({
      id,
    }).then((res) => {
      if (res.status === 200) {
        this.setState({
          log: res.data,
        })
        message.success(res.msg)
      } else {
        message.error(res.msg)
      }
    })
  }

  handleSkipCount = (val) => {
    console.log('val', val)
    this.setState({
      skipCount: val,
    })
  }

  render() {
    const props = {
      name: 'file',
      multiple: true,
      accept: '.xlsx,.xls,.csv',
      action: `${SUAN_PAN}/api/v1/documentCapture/upload`,
      maxCount: 1,
      onChange: (info) => {
        const { status } = info.file
        if (status !== 'uploading') {
          // console.log(info.file, info.fileList)
        }
        if (status === 'done') {
          this.setState({
            fileName: info.file.name,
            filePath: info.file.response.data.filePath,
            fileDownloadPath: info.file.response.data.fileDownloadUrl,
          })
          message.success(`${info.file.name} 上传成功`)
        } else if (status === 'error') {
          message.error(`${info.file.name} 上传失败`)
        }
      },
      beforeUpload: (file) => {
        // if (file && file.name.lastIndexOf('.csv') !== -1) {
        //   this.setState({
        //     file,
        //   })
        // } else {
        //   this.fileParsing(file)
        // }
        this.setState({
          file,
        })
        this.fileParsing(file)
        return true
      },
    }

    const {
      id, btnSelectIndex, query, tableName, visible, loding, current,
      previewData, fileName, sourceFields, targetFields, relation, previewData2,
      scripts, tableList, dataReplaceRuleId, isSkip, skipCount,
    } = this.state
    return (
      <div className={styles.page_content_with_breadcrumb}>
        <div className={styles.page_content_column}>
          <div className={`${styles.page_content_right} ${styles.page_content_right_flex}`}>
            <ProTableOperate
              toggleOperate={false} // 是否隐藏 收起/展开 按钮 (如果隐藏按钮，handleToggleSta设置属性值不生效)
              unfolded
            >
              <OperateItem align="left">
                <InputSearch
                  placeholder="请输入目标表进行搜索"
                  value={tableName}
                  onChange={(e) => {
                    this.setState({
                      tableName: e.target.value,
                    })
                  }}
                  onSearch={() => {
                    this.setState({
                      query: {
                        tableName,
                      },
                    })
                  }}
                />
              </OperateItem>
              <OperateItem itemType="btn">
                {
                  [
                    <Button
                      type="primary"
                      onClick={() => {
                        this.setState({
                          visible: true,
                        })
                      }}
                      key="new"
                    >
                      上传文件
                    </Button>,
                  ]
                }
              </OperateItem>
            </ProTableOperate>
            <ProTable
              query={query}
              rowKey="id"
              url="/api/v1/documentCapture/getCaptureList"
              columns={[
                {
                  title: '原始文件',
                  dataIndex: 'orgFileName',
                  width: '10%',
                  key: 'orgFileName',
                },
                {
                  title: '目标表',
                  dataIndex: 'targetTblName',
                  width: '10%',
                  key: 'targetTblName',
                },
                {
                  title: '状态',
                  dataIndex: 'state',
                  width: '20%',
                  key: 'state',
                  render: (text, record) => <span> <i style={{ color: statusObj[text].color }} className={`iconfont ${statusObj[text].icon}`} /> {statusObj[text].value}</span>,
                },
                {
                  title: '同步成功条数',
                  dataIndex: 'uploadNum',
                  width: '20%',
                  key: 'uploadNum',
                },
                {
                  title: '上传时间 ',
                  dataIndex: 'updateTime',
                  width: '10%',
                  key: 'updateTime',
                },
                {
                  title: '创建人 ',
                  dataIndex: 'creatorName',
                  width: '15%',
                  key: 'creatorName',
                },
                {
                  title: '操作',
                  dataIndex: 'operation',
                  width: '15%',
                  key: 'operation',
                  render: (text, record) => (
                    <ProTableOptions>
                      <span
                        key="check"
                        onClick={() => {
                          Tools.downloadFile(record.orgFilePath)
                        }}
                      >
                        下载
                      </span>
                      <span
                        key="edit"
                        onClick={() => {
                          this.getData(record.targetTblName)
                        }}
                      >
                        查看数据
                      </span>
                      <span
                        key="edit"
                        onClick={() => {
                          this.getLog(record.id)
                        }}
                      >
                        查看日志
                      </span>
                      <Popconfirm
                        title="确定要删除吗？"
                        onConfirm={() => { this.deleteDocumentCapture(record.id) }}
                        visible={this.state.visibleDele === record.id}
                        onCancel={() => { this.setState({ visibleDele: false }) }}
                        okText="是"
                        cancelText="否"
                        key="del"
                      >
                        <span onClick={() => { this.setState({ visibleDele: record.id }) }}>
                          删除
                        </span>
                      </Popconfirm>
                    </ProTableOptions>
                  ),
                },
              ]}
              loading={false}
            />
          </div>
          <Logger
            list={this.state.log || []}
            ref={this.logger}
          // hide={hide}
          />
        </div>
        <Modal
          title="上传文件"
          visible={visible}
          confirmLoading={loding}
          destroyOnClose
          width={720}
          onCancel={() => {
            this.clear()
          }}
          maskClosable={false}
          bodyStyle={{
            maxHeight: `${document.documentElement.clientHeight * 0.65}px`,
            overflowY: 'auto',
          }}
          footer={
            <div>
              <Button onClick={() => {
                this.clear()
              }}
              >取消
              </Button>
              {current > 0 ? (
                <Button
                  type="primary"
                  onClick={() => {
                    this.setState({
                      current: current - 1,
                    })
                  }}
                >上一步
                </Button>
              ) : null}
              {current !== 2 ? (
                <Button
                  type="primary"
                  onClick={() => {
                    this.setState({
                      current: current + 1,
                    })
                  }}
                >下一步
                </Button>
              ) : null}
              {current === 2 ? (
                <Button
                  type="primary"
                  onClick={() => {
                    this.saveTaskWithFromText()
                  }}
                >确认
                </Button>
              ) : null}
            </div>
          }
        >
          <div>
            <Steps size="small" current={current}>
              <Step title="选择文件" />
              <Step title="文件预览" />
              <Step title="映射数据表" />
            </Steps>
            <div className={styles.step_center}>
              <div style={{ display: current === 0 ? 'block' : 'none' }}>
                <Dragger {...props}>
                  <p className="ant-upload-drag-icon">
                    {/* <InboxOutlined /> */}
                    <i className="iconfont icon-cunchu" />
                  </p>
                  <p className="ant-upload-text">将文件拖拽至此，或单击直接上传</p>
                  <p className="ant-upload-hint">
                    支持扩展名：xlsx、xls、csv
                  </p>
                </Dragger>
                <br />
                {fileName && fileName.lastIndexOf('.csv') !== -1 ? (
                  <Form.Item label="编码格式">
                    <Select
                      defaultValue="UTF-8"
                      onChange={(value) => {
                        this.setState({
                          encodeFormat: value,
                        }, () => {
                          this.fileParsing(this.state.file)
                        })
                      }}
                    >
                      <Option key="UTF-8" value="UTF-8">
                        UTF-8
                      </Option>
                      <Option key="GBK" value="GBK">
                        GBK
                      </Option>
                    </Select>
                  </Form.Item>
                ) : null}
              </div>
              {current === 1 ? (
                <div>
                  <div className={`${styles.file_name} ${styles.text_overflow_single}`}><i className="iconfont icon-huixingzhen1" /> {fileName}</div>
                  <ProTable
                    columns={previewData.columns}
                    dataSource={previewData.data}
                    scroll={{ x: 700 }}
                    showHeader
                    pagination={false}
                    emptyText="暂无数据"
                  />
                </div>
              ) : null}
              {current === 2 ? (
                <div>
                  <div className={styles.field_mapping}>
                    <div className={`${styles.file_item}`}>
                      {/* <Checkbox */}
                      {/*  checked={isSkip} */}
                      {/*  onChange={(e) => { */}
                      {/*    this.setState({ */}
                      {/*      isSkip: e.target.checked, */}
                      {/*    }) */}
                      {/*  }} */}
                      {/* >跳过第一行 */}
                      {/* </Checkbox> */}
                      跳过 <InputNumber value={skipCount} min={0} max={1000000} className={styles.inp} onChange={this.handleSkipCount} /> 行
                    </div>
                    <Form.Item label="规则替换">
                      <Select
                        placeholder="请选择规则替换"
                        value={dataReplaceRuleId}
                        onChange={(value) => {
                          this.setState({
                            dataReplaceRuleId: value,
                          })
                        }}
                      >
                        <Option value={1}>写入前清理已有数据 Insert Overwrite</Option>
                        <Option value={2}>写入前保留已有数据 Insert Into</Option>
                      </Select>
                    </Form.Item>
                    <div className={`${styles.file_name} ${styles.text_overflow_single}`}><i className="iconfont icon-huixingzhen1" /> {fileName}</div>
                    <Button
                      className={styles.file_button}
                      onClick={() => {
                        this.createSql()
                      }}
                    >一键建表
                    </Button>
                    <Select
                      className={styles.file_select}
                      placeholder="请选择数据表"
                      value={this.state.table}
                      showSearch
                      optionFilterProp="children"
                      filterOption={(input, option) => option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
                      filterSort={(optionA, optionB) => optionA.children.toLowerCase().localeCompare(optionB.children.toLowerCase())}
                      onChange={(value, e) => {
                        this.setState({
                          tblId: e.key,
                          table: value,
                          relation: [],
                        }, () => {
                          this.getTableField(value)
                        })
                      }}
                    >
                      {tableList && tableList.map((item) => <Option key={item.tblIdStr} value={item.tableName}>{item.tableName}</Option>)}
                    </Select>
                  </div>
                  <div className={styles.field_mapping_box}>
                    <div className={styles.btn_wrap}>
                      <span className={`${btnSelectIndex === 1 ? styles.on : ''}`} onClick={this.sameName}>同名映射</span>
                      <span className={`${btnSelectIndex === 0 ? styles.on : ''}`} onClick={this.sameLine}>同行映射</span>
                      {
                        relation.length > 0 && (
                          <span onClick={() => {
                            this.setState({
                              relation: [],
                              btnSelectIndex: null,
                            })
                          }}
                          >
                            取消映射
                          </span>
                        )
                      }
                    </div>
                    <FieldMapping
                      {...{
                        source: {
                          data: sourceFields,
                          columns: sourceCols,
                          mutiple: false,
                        },
                        target: {
                          data: targetFields,
                          columns: targetCols,
                          mutiple: false,
                        },
                        relation,
                        // edit: !disabled,
                        onChange: (relations) => {
                          this.setState({
                            relation: relations,
                          })
                        },
                      }}
                    />
                  </div>
                </div>
              ) : null}
            </div>
          </div>
        </Modal>
        <Modal
          destroyOnClose
          title="查看数据"
          width="7rem"
          visible={this.state.dataShows}
          confirmLoading={this.state.confirmLoading}
          onOk={() => {
            this.setState({
              dataShows: false,
            })
          }}
          bodyStyle={{
            height: `${document.documentElement.clientHeight * 0.65}px`,
            overflowY: 'auto',
          }}
          onCancel={() => {
            this.setState({
              dataShows: false,
            })
          }}
          footer={false}
        >
          <div className={styles.CreateDiff_Editor_Modal}>
            <ProTable
              pagination={false}
              columns={previewData2.columns}
              dataSource={previewData2.data}
              scroll={{ x: 700 }}
              emptyText="暂无数据"
            />
          </div>
        </Modal>
        <Modal
          destroyOnClose
          title="一键建表"
          width="7rem"
          visible={this.state.isShows}
          confirmLoading={this.state.confirmLoading}
          onOk={() => {
            this.createTable()
          }}
          onCancel={() => {
            this.setState({
              isShows: false,
            })
          }}
        >
          <div className={styles.CreateDiff_Editor_Modal}>
            <CreateDiffEditor
              restData={scripts || ''}
              valueChange={this.valueChange}
              language="sql"
              editorId="data-target-editor-1"
            />
          </div>
        </Modal>
      </div>
    )
  }
}
